package com.atguigu.gmall.seckill.task;

import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.seckill.mapper.SeckillGoodsMapper;
import com.atguigu.gmall.seckill.util.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * @author wjh
 * @version 1.0
 * @date 2021/7/15 10:18
 * 秒杀商品存入缓存的定时任务
 */
@Component
public class SecKillTask {

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;

    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 秒杀商品存入redis缓存的定时任务
     */
    @Scheduled(cron = "0/15 * * * * *")
    public void secKillIntoRedisTask(){
        //计算时间段:五个时间段
        List<Date> dateMenus = DateUtil.getDateMenus();
        for (Date dateMenu : dateMenus) {
            //从数据库中查询出对应时间段的商品数据,将dateMenu的时间格式改为yyyy-MM-dd HH:mm
            //开始时间 2021-07-15 10:00
            String startTime = DateUtil.data2str(dateMenu, DateUtil.PATTERN_YYYY_MM_DDHHMM);
            //结算时间段的截止时间：2021-7-15 12:00
            Date date = DateUtil.addDateHour(dateMenu, 2);
            //结束时间
            String endTime = DateUtil.data2str(date, DateUtil.PATTERN_YYYY_MM_DDHHMM);
            //拼接条件
            LambdaQueryWrapper<SeckillGoods> wrapper = new LambdaQueryWrapper<>();
            //满足审核条件
            wrapper.eq(SeckillGoods::getStatus,"1");
            //商品的剩余库存大于0
            wrapper.gt(SeckillGoods::getStockCount,0);
            //startTime<= 开始时间 结束时间< endTime
            wrapper.ge(SeckillGoods::getStartTime,startTime);
            wrapper.le(SeckillGoods::getEndTime,endTime);
            //redis中没有此数据
            //存入redis:2020071510
            String key = DateUtil.data2str(dateMenu, DateUtil.PATTERN_YYYYMMDDHH);
            Set keys = redisTemplate.boundHashOps("SeckillGoods_" + key).keys();
            if (keys != null && keys.size() > 0){
                wrapper.notIn(SeckillGoods::getId,keys);
            }
            //查询数据库数据
            List<SeckillGoods> seckillGoods = seckillGoodsMapper.selectList(wrapper);
            //存入Redis: SeckillGoods_
            for (SeckillGoods seckillGood : seckillGoods) {
                //使用boundValueOps的话会覆盖到商品
                // 每个事件段下每个id对应商品，使用Hash
                redisTemplate.boundHashOps("SeckillGoods_" + key).put(seckillGood.getId(),seckillGood);
                //获取商品的库存数量1000个
                Integer stockCount = seckillGood.getStockCount();
                //构建一个数量长度的数组
                String[] ids = getSeckillGoodsQueue(seckillGood.getId(),stockCount);
                //将数组中的每个元素都存储到redis的list队列中去
                redisTemplate.boundListOps("seckillGoodsQueue_" + seckillGood.getId()).leftPushAll(ids);
                //库存进行记录
                redisTemplate.boundHashOps("SeckillGoodsStockNum").increment(seckillGood.getId(),stockCount);
            }
        }
    }

    /**
     * 构建商品个数长度的数组
     * @param goodsId
     * @param stockCount
     * @return
     */
    private String[] getSeckillGoodsQueue(String goodsId,Integer stockCount) {
        //构建一个库存长度的数组
        String[] ids = new String[stockCount];
        //元素填充
        for (Integer i = 0; i < stockCount; i++) {
            ids[i] = goodsId;
        }
        //返回数据
        return ids;
    }
//
//    public static void main(String[] args) {
//        List<Date> dateMenus = DateUtil.getDateMenus();
//        for (Date dateMenu : dateMenus) {
//            System.out.println(dateMenu);
//        }
//
//    }
}
